package com.haohan.cloud.scm.product.core.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.haohan.cloud.scm.api.constant.enums.opc.AllocateTypeEnum;
import com.haohan.cloud.scm.api.constant.enums.product.ExitStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.product.ExitTypeEnum;
import com.haohan.cloud.scm.api.constant.enums.product.ProductionTypeEnum;
import com.haohan.cloud.scm.api.constant.enums.product.ShipOrderStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.saleb.BuyOrderStatusEnum;
import com.haohan.cloud.scm.api.opc.entity.SummaryOrder;
import com.haohan.cloud.scm.api.opc.entity.TradeOrder;
import com.haohan.cloud.scm.api.opc.feign.SummaryOrderFeignService;
import com.haohan.cloud.scm.api.opc.feign.TradeOrderFeignService;
import com.haohan.cloud.scm.api.opc.req.TradeOrderReq;
import com.haohan.cloud.scm.api.product.entity.ProductionTask;
import com.haohan.cloud.scm.api.product.entity.ShipOrder;
import com.haohan.cloud.scm.api.product.entity.ShipOrderDetail;
import com.haohan.cloud.scm.api.product.req.AddShipReq;
import com.haohan.cloud.scm.api.product.req.ArriveBatchReq;
import com.haohan.cloud.scm.api.product.req.ProductDeliveryReq;
import com.haohan.cloud.scm.api.saleb.entity.BuyOrder;
import com.haohan.cloud.scm.api.saleb.entity.BuyOrderDetail;
import com.haohan.cloud.scm.api.saleb.req.BuyOrderReq;
import com.haohan.cloud.scm.api.saleb.req.UpdateBuyOrderStatusReq;
import com.haohan.cloud.scm.api.wms.entity.ExitWarehouseDetail;
import com.haohan.cloud.scm.api.wms.feign.ExitWarehouseDetailFeignService;
import com.haohan.cloud.scm.common.tools.exception.ErrorDataException;
import com.haohan.cloud.scm.common.tools.util.RUtil;
import com.haohan.cloud.scm.product.core.IShipOrderService;
import com.haohan.cloud.scm.product.service.ProductionTaskService;
import com.haohan.cloud.scm.product.service.ShipOrderDetailService;
import com.haohan.cloud.scm.product.service.ShipOrderService;
import com.haohan.cloud.scm.product.utils.ScmProductUtils;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * @author xwx
 * @date 2019/5/27
 */
@Service
@AllArgsConstructor
public class IShipOrderServiceImpl implements IShipOrderService {

    private final TradeOrderFeignService tradeOrderFeignService;
    private final ShipOrderService shipOrderService;
    private final ShipOrderDetailService shipOrderDetailService;
    private final SummaryOrderFeignService summaryOrderFeignService;
    private final ProductionTaskService productionTaskService;
    private final ExitWarehouseDetailFeignService exitWarehouseDetailFeignService;
    private final ScmProductUtils scmProductUtils;

    /**
     * 生成送货单
     *
     * @param req  pmId   buyId
     * @return
     */
    @Override
    public ShipOrder addShipOrder(AddShipReq req) {
        //查询交易单列表
        TradeOrderReq tradeOrderReq = new TradeOrderReq();
        tradeOrderReq.setBuyId(req.getBuyId());
        R r = tradeOrderFeignService.getTradeOrderList(tradeOrderReq, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r)) {
            throw new ErrorDataException("查询交易单列表失败");
        }
        List<TradeOrder> orderList = new ArrayList<>();
        ShipOrderDetail shipOrderDetail;
        List list = (List) r.getData();
        String buyerId = "";
        String pmId = "";
        String shipId = "123";
        for (Object data : list) {
            shipOrderDetail = new ShipOrderDetail();
            TradeOrder order = BeanUtil.toBean(data, TradeOrder.class);
            buyerId = order.getBuyerId();
            pmId = order.getPmId();
            shipOrderDetail.setPmId(order.getPmId());
            shipOrderDetail.setShipId(shipId);
            shipOrderDetail.setTradeId(order.getTradeId());
            shipOrderDetail.setGoodsName(order.getGoodsName());
            shipOrderDetail.setGoodsNum(order.getBuyNum());
            //保存送货单明细
//            shipOrderDetailService.save(shipOrderDetail);
            orderList.add(order);
        }
        // TODO 编号
        ShipOrder shipOrder = new ShipOrder();
        shipOrder.setPmId(pmId);
        shipOrder.setStatus(ShipOrderStatusEnum.wait);
        shipOrder.setBuyerId(buyerId);
        shipOrder.setShipId(shipId);
//        shipOrderService.save(shipOrder);
        return shipOrder;
    }

    /**
     * 库存满足时  运营 发起送货
     *
     * @param req
     * @return
     */
    @Override
    public Boolean initiateDelivery(ProductDeliveryReq req) {
        // 入参:汇总单编号 返回SummaryOrder信息
        R orderResult = summaryOrderFeignService.getById(req.getSummaryOrderId(), SecurityConstants.FROM_IN);
        if (RUtil.isSuccess(orderResult) == false) {
            return false;
        }
        SummaryOrder order = BeanUtil.toBean(orderResult.getData(), SummaryOrder.class);
        // 修改调配类型2.库存 并保存
        order.setAllocateType(AllocateTypeEnum.stock);
        R save = summaryOrderFeignService.save(order, SecurityConstants.FROM_IN);
        if (RUtil.isSuccess(save) == false) {
            return false;
        }
        // 创建生产任务(配送)
        ProductionTask task = this.addProductionTask(order, req.getUserId());
        //创建并返回出库明细
        return this.addExitWarehouseDetail(task);
    }

    /**
     * 创建生产任务
     *
     * @param order
     * @return
     */
    @Override
    public ProductionTask addProductionTask(SummaryOrder order, String userId) {
        ProductionTask task = new ProductionTask();
        BeanUtil.copyProperties(order, task);
        task.setProductionType(ProductionTypeEnum.delivery);
        // TODO 根据ID查询发起人及名称
        task.setGoodsModelName(order.getGoodsModel());
        task.setNeedNumber(order.getNeedBuyNum());
        task.setDeliveryDate(order.getDeliveryTime());
        if (productionTaskService.save(task) == false) {
            throw new ErrorDataException("创建生产任务失败");
        }
        return task;
    }

    /**
     * 创建出库明细
     *
     * @param task
     * @return
     */
    @Override
    public Boolean addExitWarehouseDetail(ProductionTask task) {
        ExitWarehouseDetail detail = new ExitWarehouseDetail();
        //TODO 数据转换
        BeanUtil.copyProperties(task, detail);
        detail.setProductNumber(task.getNeedNumber());
        detail.setExitStatus(ExitStatusEnum.wait);
        detail.setExitType(ExitTypeEnum.delivery);
        detail.setProductionTaskSn(task.getProductionTaskSn());
        R r = exitWarehouseDetailFeignService.save(detail, SecurityConstants.FROM_IN);
        if (RUtil.isSuccess(r) == false) {
            return false;
        }
        return true;
    }

    /**
     * 开始配送 改变配送单状态 修改B订单状态
     * 失败时抛出异常
     *
     * @param shipOrder 需完整信息 pmId/shipId/buyId
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deliveryBegin(ShipOrder shipOrder) {
        ShipOrder update = new ShipOrder();
        update.setStatus(ShipOrderStatusEnum.delivery);
        update.setAcceptTime(LocalDateTime.now());
        UpdateWrapper<ShipOrder> updateWrapper = new UpdateWrapper<>();
        // 状态需为 待配送
        updateWrapper.lambda()
                .eq(ShipOrder::getPmId, shipOrder.getPmId())
                .eq(ShipOrder::getShipId, shipOrder.getShipId())
                .eq(ShipOrder::getStatus, ShipOrderStatusEnum.wait);
        if (!shipOrderService.update(update, updateWrapper)) {
            throw new ErrorDataException("配送单有误");
        }
        // 配送明细
        QueryWrapper<ShipOrderDetail> query = new QueryWrapper<>();
        query.lambda()
                .eq(ShipOrderDetail::getPmId, shipOrder.getPmId())
                .eq(ShipOrderDetail::getShipId, shipOrder.getShipId());
        List<ShipOrderDetail> detailList = shipOrderDetailService.list(query);
        if (CollUtil.isEmpty(detailList)) {
            throw new ErrorDataException("配送单有误,无明细信息");
        }
        List<BuyOrderDetail> buyOrderDetailList = new ArrayList<>();
        BuyOrderDetail buyOrderDetail;
        for (ShipOrderDetail detail : detailList) {
            buyOrderDetail = new BuyOrderDetail();
            buyOrderDetail.setBuyDetailSn(detail.getBuyDetailSn());
            buyOrderDetail.setStatus(BuyOrderStatusEnum.arrive);
            buyOrderDetailList.add(buyOrderDetail);
        }
        // 修改 B订单 改为 待收货
        UpdateBuyOrderStatusReq updateReq = new UpdateBuyOrderStatusReq();
        updateReq.setPmId(shipOrder.getPmId());
        updateReq.setBuyId(shipOrder.getBuyId());
        updateReq.setStatus(BuyOrderStatusEnum.arrive);
        updateReq.setDetailList(buyOrderDetailList);
        if (!scmProductUtils.updateBuyOrderStatus(updateReq)) {
            throw new ErrorDataException("B订单更新失败");
        }
    }

    /**
     * 配送单 送达  修改配送单状态
     * @param shipOrder 必须 pmId/shipId
     */
    @Override
    public void arrive(ShipOrder shipOrder) {
        ShipOrder update = new ShipOrder();
        update.setStatus(ShipOrderStatusEnum.success);
        update.setArriveTime(LocalDateTime.now());
        UpdateWrapper<ShipOrder> updateWrapper = new UpdateWrapper<>();
        // 状态需为 待配送
        updateWrapper.lambda()
                .eq(ShipOrder::getPmId, shipOrder.getPmId())
                .eq(ShipOrder::getShipId, shipOrder.getShipId());
        if (!shipOrderService.update(update, updateWrapper)) {
            throw new ErrorDataException("配送单有误");
        }
    }


    /**
     * 配送单批量送达
     * @param req 必须 pmId、DeliveryTime、BuySeq
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String arriveBatch(ArriveBatchReq req) {
        String pmId = req.getPmId();
        // 当前时间批次的 B订单
        BuyOrderReq buyOrder = new BuyOrderReq();
        buyOrder.setPmId(pmId);
        buyOrder.setDeliveryTime(req.getDeliveryDate());
        buyOrder.setBuySeq(req.getDeliverySeq());
        List list = scmProductUtils.queryBuyOrderList(buyOrder);
        if(null == list){
            return null;
        }
        int success = 0;
        int failed = 0;
        LocalDateTime now = LocalDateTime.now();
        for(Object obj: list){
            BuyOrder order = BeanUtil.toBean(obj, BuyOrder.class);
            String buyId = order.getBuyId();
            if(StrUtil.isEmpty(buyId)){
                continue;
            }
            // 送达
            ShipOrder update = new ShipOrder();
            update.setStatus(ShipOrderStatusEnum.success);
            update.setArriveTime(now);
            UpdateWrapper<ShipOrder> updateWrapper = new UpdateWrapper<>();
            // 状态需为 配送中
            updateWrapper.lambda()
                    .eq(ShipOrder::getPmId, pmId)
                    .eq(ShipOrder::getStatus, ShipOrderStatusEnum.delivery)
                    .eq(ShipOrder::getBuyId, buyId);
            if (shipOrderService.update(update, updateWrapper)) {
                success++;
            }else {
                failed++;
            }
        }
        if(success==0){
            return null;
        }
        return "当前时间批次确认送达订单数:" + success + ", 未送达订单数:" + failed;
    }

}

